package cn.bjnangle.mytrack;

import android.app.Activity;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class EchoUDPServer extends Activity implements View.OnClickListener {
    private int port = 6666;
    private DatagramSocket socket;
    private static int minBufferSize = 0;
    private AudioRecord audioRecord;
    private static AudioTrack mAudioTrack;
    private static final int RECORD_AUDIO_BUFFER_TIMES = 1;
    private boolean b = false;
    private int bufferSize;
    private String ipC = "30.30.30.62";
    private String portC = "9000";
    private AudioManager audioManager;
    private DatagramPacket recePacket;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_server);
        findViewById(R.id.start_btn).setOnClickListener(this);
        findViewById(R.id.stop_btn).setOnClickListener(this);
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
        mAudioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize * 2, AudioTrack.MODE_STREAM);

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == 139){
            audioManager.setMode(AudioManager.MODE_NORMAL);
            audioManager.setSpeakerphoneOn(true);
        }else if(keyCode == 138){
            audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            audioManager.setSpeakerphoneOn(false);
        }

        return super.onKeyDown(keyCode, event);
    }

    private void start() {
        b = true;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        bufferSize = AudioRecord.getMinBufferSize(44100,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT) * RECORD_AUDIO_BUFFER_TIMES;
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 44100,
                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, 2048);
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    mAudioTrack.play();
                    while (b) {
                        byte[] receBuf = new byte[2048];
                        recePacket = new DatagramPacket(receBuf, receBuf.length);

                        try {
                            socket.receive(recePacket);
                            byte[] datas = recePacket.getData();
                            int readCount = datas.length;
                            if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {
                                continue;
                            }
                            if (readCount != 0 && readCount != -1) {
                                mAudioTrack.write(datas, 0, readCount);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (mAudioTrack != null) {
                        if (mAudioTrack.getState() == AudioRecord.STATE_INITIALIZED) {//初始化成功
                            mAudioTrack.stop();//停止播放
                        }
                        if (mAudioTrack != null) {
                            mAudioTrack.release();//释放audioTrack资源
                        }

                    }
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                super.run();
                byte[] byteBuffer = new byte[2048];
                try {
                    audioRecord.startRecording();
                    while (b) {
                        int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);
                        sendByte(byteBuffer);
                    }
                    audioRecord.stop();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }

            }
        }.start();
    }

    private void sendByte(byte buf[]) {
        DatagramPacket dp_send = new DatagramPacket(buf, buf.length);
        dp_send.setSocketAddress(new InetSocketAddress(ipC, Integer.valueOf(portC)));
        try {
            socket.send(dp_send);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mAudioTrack != null) {
            if (mAudioTrack.getState() == AudioRecord.STATE_INITIALIZED) {//初始化成功
                mAudioTrack.stop();//停止播放
            }
            if (mAudioTrack != null) {
                mAudioTrack.release();//释放audioTrack资源
            }

        }
        if(audioRecord!=null){
            audioRecord = null;
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.start_btn) {
            start();
        }
        if (v.getId() == R.id.stop_btn) {
            stop();
        }
    }

    public void stop() {
        b = false;
        if (socket != null) {
            socket.close();
        }
        EchoUDPServer.this.finish();
    }




    /**
     * byte转short
     * @param data
     * @return
     */
    public static short[] byteToShort(byte[] data) {
        short[] shortValue = new short[data.length / 2];
        for (int i = 0; i < shortValue.length; i++) {
            shortValue[i] = (short) ((data[i * 2] & 0xff) | ((data[i * 2 + 1] & 0xff) << 8));
        }
        return shortValue;
    }



    /**
     * short转byte
     * @param data
     * @return
     */
    public static byte[] shortToByte(short[] data) {
        byte[] byteValue = new byte[data.length * 2];
        for (int i = 0; i < data.length; i++) {
            byteValue[i * 2] = (byte) (data[i] & 0xff);
            byteValue[i * 2 + 1] = (byte) ((data[i] & 0xff00) >> 8);
        }
        return byteValue;
    }
}

